<template>
	<div>
		<!-- 面包屑导航 -->
		<el-breadcrumb separator-class="el-icon-arrow-right">
			<el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
			<el-breadcrumb-item>权限管理</el-breadcrumb-item>
			<el-breadcrumb-item>角色列表</el-breadcrumb-item>
		</el-breadcrumb>
		<!-- 卡片式图 -->
		<el-card class="box-card">
			<!-- 添加角色按钮区 -->
			<el-row>
				<el-col>
					<el-button type="primary" @close="addDialogclosed" :visible.sync="addDialogVisible" width="50%"
						@click="addDialogVisible=true">添加角色</el-button>
				</el-col>
			</el-row>
			<!-- 角色列表区 -->
			<el-table :data="rolelist" border stripe>
				<!-- 展开列 -->
				<el-table-column type="expand">
					<template slot-scope="scope">
						<el-row :class="[i1 === 0 ?'bdtop':'bdbottom','vcenter']"
							v-for="(item1,i1) in scope.row.children" :key="item1.id">
							<!-- 渲染一级权限 -->
							<el-col :span="5">
								<el-tag closable type="danger" @close="removeRightbyid(scope.row,item1.id)">
									{{item1.authName}}
								</el-tag>
								<i class="el-icon-caret-right"></i>
							</el-col>
							<!-- 渲染二三级权限 -->
							<el-col :span="19">
								<!-- 通过for循环渲染二级权限 -->
								<el-row :class="[i2 === 0?'':'bdtop','vcenter']" v-for="(item2,i2) in item1.children"
									:key="item2.id">
									<el-col :span="6">
										<el-tag closable type="success" @close="removeRightbyid(scope.row,item2.id)">
											{{item2.authName}}
										</el-tag>
										<i class="el-icon-caret-right"></i>
									</el-col>
									<el-col :span="18">
										<el-tag closable type="warning" v-for="(item3,i3) in item2.children"
											:key="item3.id" @close="removeRightbyid(scope.row,item3.id)">
											{{item3.authName}}
										</el-tag>
									</el-col>
								</el-row>

							</el-col>
						</el-row>
						<!-- pre json格式化数据展示 -->
						<!-- 	<pre>
						{{scope.row}}
						</pre> -->
					</template>
				</el-table-column>
				<!-- 索引列 -->
				<el-table-column type="index" label="#"></el-table-column>
				<el-table-column label="角色名称" prop="roleName"></el-table-column>
				<el-table-column label="角色描述" prop="roleDesc"></el-table-column>
				<el-table-column label="操作">
					<template slot-scope="scope">
						<el-button size="mini" type="primary" icon="el-icon-edit" @click="showEditDialog(scope.row.id)">
							编辑</el-button>
						<el-button size="mini" type="danger" icon="el-icon-delete "
							@click="removeUserById(scope.row.id)">删除</el-button>
						<el-button size="mini" type="warning" icon="el-icon-setting "
							@click="showSetRightDialog(scope.row)">分配权限</el-button>
					</template>
				</el-table-column>
			</el-table>

		</el-card>
		<!-- 添加角色的对话框 -->
		<el-dialog title="添加角色:" @close="addDialogclosed" :visible.sync="addDialogVisible" width="50%">
			<!-- 内容主体区域 -->

			<el-form :model="addForm" :rules="addFormRules" ref="addFormRef" label-width="100px">
				<el-form-item label="角色名称" prop="roleName">
					<el-input v-model="addForm.roleName"></el-input>
				</el-form-item>
				<el-form-item label="角色描述" prop="roleDesc">
					<el-input v-model="addForm.roleDesc"></el-input>
				</el-form-item>

			</el-form>

			<!-- 底部区域 -->
			<span slot="footer" class="dialog-footer">
				<el-button @click="addDialogVisible = false">取 消</el-button>
				<el-button type="primary" @click="addUser()">确 定</el-button>
			</span>
		</el-dialog>
		<!-- 修改角色的对话框 -->
		<el-dialog title="修改角色" @close="editDialogclosed" :visible.sync="editDialogVisible" width="50%">
			<el-form :model="editForm" :rules="editFormrules" ref="editFormRef" label-width="70px">
				<el-form-item label="角色名称">
					<el-input disabled v-model="editForm.roleName"></el-input>
				</el-form-item>
				<el-form-item label="角色描述" prop="roleDesc">
					<el-input v-model="editForm.roleDesc"></el-input>
				</el-form-item>

			</el-form>
			<span slot="footer" class="dialog-footer">
				<el-button @click="editDialogVisible = false">取 消</el-button>
				<el-button type="primary" @click="edituserinfo">确 定</el-button>
			</span>
		</el-dialog>

		<!-- 分配权限的对话框 -->
		<el-dialog title="分配权限" :visible.sync="setRightdialogVisible" width="50%" @close="setRightDialogClosed">
			<el-tree :data="rightslist" :props="treeProps" show-checkbox node-key="id" default-expand-all
				:default-checked-keys="defkeys" ref="treeRef"></el-tree>
			<span slot="footer" class="dialog-footer">
				<el-button @click="setRightdialogVisible = false">取 消</el-button>
				<el-button type="primary" @click="allotRights()">确 定</el-button>
			</span>
		</el-dialog>

	</div>
</template>

<script>
	export default {
		data() {
			return {
				//角色列表数据
				rolelist: [],
				// 控制分配权限对话框显示与隐藏
				setRightdialogVisible: false,
				//权限列表数据
				rightslist: [],
				//树形控件属性绑定对象
				treeProps: {
					label: 'authName',
					children: 'children'
				},
				//默认选中的节点id值数组
				defkeys: [],
				//当前即将分配权限的角色id
				roleId: '',
				//添加角色的表单数据
				addForm: {
					roleName: '',
					roleDesc: '',

				},
				//控制添加角色对话框的显示和隐藏
				addDialogVisible: false,
				//添加用户表单验证的验证规则对象
				addFormRules: {
					roleName: [{
							required: true,
							message: '角色名称',
							trigger: 'blur'
						},
						{
							min: 2,
							max: 10,
							message: '角色名的长度在3~10之间',
							trigger: 'blur'
						}
					],
					roleDesc: [{
							required: false,
							message: '角色描述',
							trigger: 'blur'
						},
						{
							min: 6,
							max: 15,
							message: '角色描述的长度在6~15之间',
							trigger: 'blur'
						}
					]


				},
				//控制修改对话框的显示和隐藏
				editDialogVisible: false,
				//用户查询到的用户信息对象
				editForm: {

				},



			}
		},
		created() {
			this.getRolesList();
		},
		methods: {
			//获取所有角色的列表
			async getRolesList() {
				const {
					data: res
				} = await this.$http.get('roles')
				if (res.meta.status != 200) {
					this.$message.error("获取角色列表失败")
				}
				this.rolelist = res.data

			},
			//根据id删除对应的权限
			async removeRightbyid(role, rightId) {
				const confirmResult = await this.$confirm('此操作将永久删除用户, 是否继续?', '提示', {
						confirmButtonText: '确定',
						cancelButtonText: '取消',
						type: 'warning'
					})
					//如果用户取消删除则 则打印cancel字符串
					.catch(err => err)
				//如果用户确认删除则confirmResult 为confim字符串

				if (confirmResult != 'confirm') {
					return this.$message.info("已经取消删除")
				}
				const {
					data: res
				} = await this.$http.delete(`roles/${role.id}/rights/${rightId}`)
				if (res.meta.status != 200) {
					this.$message.error("删除失败" + res.meta.msg)
				}
				this.$message.success("删除成功")
				//此时res中已经删除了所以res是最新的该用户权限的数据 然后再重新赋值给该行数据                   
				role.children = res.data
			},
			//分配权限的对话框事件

			async showSetRightDialog(role) {
				this.roleId = role.id
				//获取所有权限的数据列表
				const {
					data: res
				} = await this.$http.get('rights/tree')
				if (res.meta.status != 200) {
					this.$message.error("获取数据失败" + res.meta.msg)
				}
				//递归获取三级节点id
				this.getLeafkeys(role, this.defkeys)
				console.log(this.defkeys)
				//把获取到的权限数据列表放到rightlist
				this.rightslist = res.data
				this.setRightdialogVisible = true
			},
			//通过递归的方式获取权限列表三级权限的id存放到defkeys数组中
			getLeafkeys(node, arr) {
				//如果当前node节点不包含children属性则是三级节点
				if (!node.children) {
					return arr.push(node.id);
				}
				//递归
				node.children.forEach(item =>
					this.getLeafkeys(item, arr)
				)
			},
			//监听分配权限对话框关闭事件
			setRightDialogClosed() {
				//重置数组否则关闭后还保留id值
				this.defkeys = [];
			},
			//为角色分配权限
			async allotRights() {
				const keys = [
					//获取选中的id
					...this.$refs.treeRef.getCheckedKeys(),
					//获取半选中的id
					this.$refs.treeRef.getHalfCheckedKeys()
				]
				//接口需要以逗号拼接的id
				const idStr = keys.join(',')

				const {
					data: res
				} = await this.$http.post(`roles/${this.roleId}/rights`, {
					rids: idStr
				})
				if (res.meta.status != 200) {
					return this.$message.error("分配权限失败")
				}
				this.$message.success("分配权限成功")

				this.getRolesList()
				this.setRightdialogVisible = false
			},
			//监听添加角色对话框的关闭事件清除input内容
			addDialogclosed() {
				this.$refs.addFormRef.resetFields()
				console.log(this.$refs.addFormRef)
			},
			//点击按钮添加新角色
			addUser() {
				this.$refs.addFormRef.validate(async valid => {
					if (!valid) return
					//可以发起用户请求
					const {
						data: res
					} = await this.$http.post('roles', this.addForm)
					if (res.meta.status != 201) {
						this.$message.success(res.meta.msg)
					}
					this.$message.success(res.meta.msg)


					//隐藏添加角色的对话框
					this.addDialogVisible = false

					//重新获取角色列表数据
					this.getRolesList()()

				})

			},
			//展示编辑角色对话框
			async showEditDialog(id) {
				const {
					data: res
				} = await this.$http.get('roles/' + id)
				if (res.meta.status != 200) {
					return this.$message.error("查询用户数据失败")
				}
				this.editForm = res.data
				this.editDialogVisible = true
			},
			//监听角色修改对话框的关闭事件重置input框
			editDialogclosed() {
				this.$refs.editFormRef.resetFields()
			},
			//修改角色信息并提交
			edituserinfo() {
				this.$refs.editFormRef.validate(async valid => {

					if (!valid) return
					const {
						data: res
					} = await this.$http.put('roles/' + this.editForm.roleId, {
						roleName: this.editForm.roleName,
						roleDesc: this.editForm.roleDesc
					})

					if (res.meta.status != 200) {
						return this.$message.error("更新角色数据失败")
					}

					//提示成功
					this.$message.success("更新成功")
					//关闭对话框
					this.editDialogVisible = false
					//刷新列表
					this.getRolesList()



				})
			},
			//移除角色事件
			async removeUserById(id) {
				const confirmResult = await this.$confirm('此操作将永久删除用户, 是否继续?', '提示', {
						confirmButtonText: '确定',
						cancelButtonText: '取消',
						type: 'warning'
					})
					//如果用户取消删除则 则打印cancel字符串
					.catch(err => err)
				//如果用户确认删除则confirmResult 为confim字符串

				if (confirmResult != 'confirm') {
					return this.$message.info("已经取消删除")
				}
				const {
					data: res
				} = await this.$http.delete('roles/' + id)
				if (res.meta.status != 200) {
					return this.$message.error("删除失败" + res.meta.msg)
				}
				this.$message.success("删除成功")
				this.getRolesList();
			}



		}



	}
</script>

<style lang="less" scoped="scoped">
	.el-tag {
		margin: 9px;
	}

	.bdtop {
		border-top: 1px solid #eee;
	}

	.bdbottom {
		border-bottom: 1px solid #eee;
	}

	.vcenter {
		display: flex;
		align-items: center;
	}
</style>
